#include "fig_enemy_craft.h"
#include "fighter.h"
#include "fig_flyingpath.h"
#include "fig_player_craft.h"
#include "fig_pickup_manager.h"
#include "fig_functions.h"
#include "fig_constants.h"

#include "dd/dd_man.h"
#include "math/facing.h"

#include "num/rand.h"
#include "application/game_script.h"
#include "console/console.h"
#include "ui/ui_manager.h"
#include "gameflow/game_flow_manager.h"
#include "dd/dd_man.h"
#include "font/font_manager.h"
#include "script/scripthelper.h"
#include "input/keyboard.h"
#include "graphics/graphics_util.h"
#include "luaplus/LuaObject.h"
#include "script/scripthelper.h"
#include "script/write_lua.h"
#include "lang/lang.h"
#include "vfs/vfs.h"
#include "script/file_list.h"

#include "font/font_manager.h"
#include "util/mmgr.h"		    // Needs to come in early
#include "util/common_macros.h"		// macros
#include "util/log.h"		    // logging
#include "util/timer.h"		    // logging


FIGEnemyCraft::FIGEnemyCraft(ENEMY_TYPES EnemyType) : 
										FIGCraft(),
										m_EnemyType(EnemyType),
										m_RotationSpeed(0.1f),
										m_TargetRotation(0),										
										m_DelaySpawn(0.0f),
										m_Accel(1.0f),
										m_IsBoss(false),
										m_SpawnPickup(FIGPickup::PICKUP_TYPE_NONE)
{
	m_DamageForColliding = (float)FIGConstants::PLAYER_HP * 0.25f;
	m_Pos = math::Vec2( 0.5f,0.5f);	
	m_Rotation = 360;
	m_MoveAbitCounter.SetLimit(0.9f);
	m_MoveAbitCounter.ForceReady();
}


void		FIGEnemyCraft::Render(const math::Vec2& Offset, float Scale)
{
	if(m_DelaySpawn > 0)
		return;
	
	FIGCraft::Render(Offset, Scale);
}

void		FIGEnemyCraft::Tick(float dt)
{
	
	if(m_DelaySpawn > 0)
	{
		m_DelaySpawn -= dt;
		return;
	}

	FIGCraft::Tick(dt);

	if(!m_IsAlive)
		return;

	if(FIGPlayerCraft::Instance().CanHit() && 
		HitTest((FIGLifeObj*)&FIGPlayerCraft::Instance()))
	{
		FIGPlayerCraft::Instance().GotDamage(this->GetDamageForColliding(),NULL, false);
		if(!m_IsBoss)
			GotDamage(100,NULL, false);
	}

	

}



void	FIGEnemyCraft::MoveAbit(float dt, float BottomLimit)
{
	m_MoveAbitCounter.Tick(dt);
	if(m_MoveAbitCounter.IsReady())
	{
		
		// get new position
		m_MoveAbitCounter.Reset();
		float X = num::RAND32::Instance().RandFloat( 0.0f + m_Radius , 1.0f - m_Radius);
		float Y = num::RAND32::Instance().RandFloat( 0.0f + m_Radius  ,BottomLimit );

		math::Vec2 TargetPos = math::Vec2(X,Y);
		m_MoveAbitDir = TargetPos - m_Pos;
		m_MoveAbitDir.Normalize();
		
		
	}
	else
	{
		m_Pos += m_MoveAbitDir * dt * 0.08f;
	}

}

bool		FIGEnemyCraft::Tick_ComeIn(float dt,float BottomLimit)
{	
	math::Vec2 Dir = math::Vec2(0,1.0f);
	float Dist = dt * m_Speed;
	m_Pos += ( Dir * Dist);

	if(m_Pos.y > BottomLimit * 0.5f)
	{
		//slow Down
		m_Speed -= ( m_Accel * dt);
		if(m_Speed < 0.1f)
			m_Speed = 0.1f;
	}

	if(m_Pos.y > BottomLimit)
		return true;
		
	return false;
}

void	FIGEnemyCraft::AimToPlayer(float dt)
{
	
	math::Vec2 PlayerPos = FIGPlayerCraft::Instance().GetPos();
	math::Vec2 MyPos = m_Pos;

	float Angle = math::Facing::AngleFromTo(MyPos , PlayerPos);
	Angle += 180;
	m_TargetRotation = Angle;
	
	FigFunctions::ToDegree(m_Rotation,m_TargetRotation,m_RotationSpeed * dt);

		
}

void	FIGEnemyCraft::OnDie()
{
	FIGCraft::OnDie();
	if(m_SpawnPickup > FIGPickup::PICKUP_TYPE_NONE)
	{
		FIGPickupManager::Instance().Spawn(m_SpawnPickup,m_Pos);
	}
}

void		FIGEnemyCraft::InitSpawning(
										float Delay,
										float PosX,
										FIGPickup::PICKUP_TYPES PickupType
										)
{
	m_DelaySpawn = Delay;
	m_Pos.x = PosX;
	m_SpawnPickup = PickupType;
}

std::string		FIGEnemyCraft::MapTypeToBoneFile(ENEMY_TYPES Type)
{
	switch (Type)
	{
		
		case ENEMY_TYPES_TRIANGLE:
		return "transform/miniboss_triangle.lua";

		case ENEMY_TYPES_MINIBOSS_HULK:
		return "transform/miniboss_hulk.lua";

		case ENEMY_TYPES_MINIBOSS_COBRA:
		return "transform/miniboss_cobra.lua";

		case ENEMY_TYPES_MINIBOSS_MEGANITO:
		return "transform/miniboss_meganito.lua";

		case ENEMY_TYPES_MINIBOSS_FOX:
		return "transform/miniboss_fox.lua";

		case ENEMY_TYPES_MINIBOSS_PRON:
			return "transform/miniboss_pron.lua";

		case ENEMY_TYPES_MINIBOSS_SHARK:
			return "transform/miniboss_shark.lua";

		case ENEMY_TYPES_MINIBOSS_PLATO:
			return "transform/miniboss_plato.lua";

		case ENEMY_TYPES_MINIBOSS_HADIEZ:
			return "transform/miniboss_hadiez.lua";

		case ENEMY_TYPES_MINIBOSS_BOMBER:
			return "transform/miniboss_bomber.lua";

		case ENEMY_TYPES_MINIBOSS_WOLF:
			return "transform/miniboss_wolf.lua";

		case ENEMY_TYPES_BOSS_HUMMER:
		return "transform/boss_hummer.lua";

		case ENEMY_TYPES_BOSS_BEAST:
		return "transform/boss_beast.lua";

		case ENEMY_TYPES_BOSS_BOFFER:
		return "transform/boss_boffer.lua";

		case ENEMY_TYPES_BOSS_DESTORYER:
		return "transform/boss_destoryer.lua";

		case ENEMY_TYPES_BOSS_PYRO:
		return "transform/boss_pyro.lua";

		case ENEMY_TYPES_BOSS_ELECTRO:
		return "transform/boss_electro.lua";

		case ENEMY_TYPES_BOSS_EYE:
		return "transform/boss_eye.lua";

		case ENEMY_TYPES_BOSS_MEGA:
		return "transform/boss_mega.lua";

		case ENEMY_TYPES_BOSS_VIPER:
		return "transform/boss_viper.lua";

		case ENEMY_TYPES_BOSS_GYVER:
		return "transform/boss_gyver.lua";

		case ENEMY_TYPES_BOSS_MONSTER:
		return "transform/boss_monster.lua";

		case ENEMY_TYPES_BOSS_EAGLE:
		return "transform/boss_eagle.lua";

		case ENEMY_TYPES_BOSS_U14:
		return "transform/boss_u14.lua";

		default:
			break;

	}

	return "";
}

std::string		FIGEnemyCraft::MapTypeToName(FIGEnemyCraft::ENEMY_TYPES Type)
{
	switch (Type)
	{
		case ENEMY_TYPES_NORMAL:
		return "normal";

		case ENEMY_TYPES_TRIANGLE:
		return "normal_triangle";

		case ENEMY_TYPES_MINIBOSS_HULK:
		return "miniboss_hulk";

		case ENEMY_TYPES_MINIBOSS_COBRA:
		return "miniboss_cobra";

		case ENEMY_TYPES_MINIBOSS_MEGANITO:
		return "miniboss_meganito";

		case ENEMY_TYPES_MINIBOSS_FOX:
		return "miniboss_fox";

		case ENEMY_TYPES_MINIBOSS_PRON:
		return "miniboss_pron";

		case ENEMY_TYPES_MINIBOSS_SHARK:
			return "miniboss_shark";

		case ENEMY_TYPES_MINIBOSS_PLATO:
			return "miniboss_plato";

		case ENEMY_TYPES_MINIBOSS_HADIEZ:
			return "miniboss_hadiez";

		case ENEMY_TYPES_MINIBOSS_BOMBER:
			return "miniboss_bomber";

		case ENEMY_TYPES_MINIBOSS_WOLF:
			return "miniboss_wolf";

		case ENEMY_TYPES_BOSS_HUMMER:
		return "boss_hummer";

		case ENEMY_TYPES_BOSS_BEAST:
		return "boss_beast";

		case ENEMY_TYPES_BACKATTACKER:
		return "backattacker";

		case ENEMY_TYPES_BOSS_BOFFER:
		return "boss_boffer";

		case ENEMY_TYPES_BOSS_DESTORYER:
		return "boss_destoryer";

		case ENEMY_TYPES_TEST:
		return "normal_test";

		case ENEMY_TYPES_BOSS_PYRO:
		return "boss_pyro";

		case ENEMY_TYPES_BOSS_ELECTRO:
		return "boss_electro";

		case ENEMY_TYPES_BOSS_EYE:
		return "boss_eye";

		case ENEMY_TYPES_BOSS_MEGA:
		return "boss_mega";

		case ENEMY_TYPES_BOSS_VIPER:
		return "boss_viper";

		case ENEMY_TYPES_BOSS_GYVER:
		return "boss_gyver";

		case ENEMY_TYPES_BOSS_MONSTER:
		return "boss_monster";

		case ENEMY_TYPES_BOSS_EAGLE:
		return "boss_eagle";

		case ENEMY_TYPES_BOSS_U14:
		return "boss_u14";

		case ENEMY_TYPES_SPACEROCK_SLOW:
		return "space_rock_slow";

		case ENEMY_TYPES_SPACEROCK_FAST:
		return "space_rock_fast";

		case ENEMY_TYPES_SPACEROCK_DECAL:
		return "space_rock_decal";

		case ENEMY_TYPES_DRAGON:
		return "dragon";

		case ENEMY_TYPES_FORMATION:
		return "formation";

		default:
			break;

	}

	return "unknown";
}

FIGEnemyCraft::ENEMY_TYPES		FIGEnemyCraft::MapNameToType(const std::string& TypeName)
{
	for (unsigned int i = 0; i < ENEMY_TYPES_COUNT; i++)
		if (strcmpi( MapTypeToName((ENEMY_TYPES)i).c_str(), TypeName.c_str() ) == 0)
			return (ENEMY_TYPES)i;

	return ENEMY_TYPES_NONE;  	
}

